package com.devenv.entity;

import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import com.fasterxml.jackson.annotation.JsonIgnore;

import jakarta.persistence.*;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 用户统计实体类
 * <p>
 * 记录用户的各项活动统计数据，包括脚本生成、模板创建使用、登录统计等
 * </p>
 * 
 * @author DevEnv OpenSource Team
 * @version 1.0.0
 * @since 1.0.0
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Entity
@Table(name = "user_statistics", indexes = {
    @Index(name = "idx_stats_user", columnList = "userId"),
    @Index(name = "idx_stats_login_date", columnList = "lastLoginDate"),
    @Index(name = "idx_stats_favorite_os", columnList = "favoriteOs")
})
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class UserStatistics {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "user_id", nullable = false, unique = true)
    private Long userId;

    @Column(name = "total_scripts_generated", nullable = false)
    private Integer totalScriptsGenerated = 0;

    @Column(name = "total_templates_created", nullable = false)
    private Integer totalTemplatesCreated = 0;

    @Column(name = "total_templates_used", nullable = false)
    private Integer totalTemplatesUsed = 0;

    @Column(name = "total_software_selected", nullable = false)
    private Integer totalSoftwareSelected = 0;

    @Column(name = "favorite_os", length = 20)
    private String favoriteOs;

    @Column(name = "favorite_category", length = 50)
    private String favoriteCategory;

    @Column(name = "total_login_days", nullable = false)
    private Integer totalLoginDays = 0;

    @Column(name = "consecutive_login_days", nullable = false)
    private Integer consecutiveLoginDays = 0;

    @Column(name = "max_consecutive_login_days", nullable = false)
    private Integer maxConsecutiveLoginDays = 0;

    @Column(name = "last_login_date")
    private LocalDate lastLoginDate;

    @Column(name = "first_login_date")
    private LocalDate firstLoginDate;

    @Column(name = "total_active_days", nullable = false)
    private Integer totalActiveDays = 0;

    @Column(name = "avg_session_duration_minutes")
    private Integer avgSessionDurationMinutes = 0;

    @Column(name = "created_at")
    private LocalDateTime createdAt;

    @Column(name = "updated_at")
    private LocalDateTime updatedAt;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", insertable = false, updatable = false)
    @JsonIgnore
    private User user;

    @PrePersist
    protected void onCreate() {
        createdAt = LocalDateTime.now();
        updatedAt = LocalDateTime.now();
    }

    @PreUpdate
    protected void onUpdate() {
        updatedAt = LocalDateTime.now();
    }

    /**
     * 增加脚本生成次数
     */
    public void incrementScriptGeneration() {
        this.totalScriptsGenerated = (this.totalScriptsGenerated == null ? 0 : this.totalScriptsGenerated) + 1;
    }

    /**
     * 增加模板创建次数
     */
    public void incrementTemplateCreation() {
        this.totalTemplatesCreated = (this.totalTemplatesCreated == null ? 0 : this.totalTemplatesCreated) + 1;
    }

    /**
     * 增加模板使用次数
     */
    public void incrementTemplateUsage() {
        this.totalTemplatesUsed = (this.totalTemplatesUsed == null ? 0 : this.totalTemplatesUsed) + 1;
    }

    /**
     * 增加软件选择次数
     */
    public void incrementSoftwareSelection(int count) {
        this.totalSoftwareSelected = (this.totalSoftwareSelected == null ? 0 : this.totalSoftwareSelected) + count;
    }

    /**
     * 更新登录统计
     */
    public void updateLoginStats(LocalDate loginDate) {
        if (this.lastLoginDate == null) {
            // 首次登录
            this.totalLoginDays = 1;
            this.consecutiveLoginDays = 1;
            this.maxConsecutiveLoginDays = 1;
            this.firstLoginDate = loginDate;
        } else if (this.lastLoginDate.equals(loginDate)) {
            // 同一天重复登录，不更新
            return;
        } else if (this.lastLoginDate.plusDays(1).equals(loginDate)) {
            // 连续登录
            this.totalLoginDays++;
            this.consecutiveLoginDays++;
            if (this.consecutiveLoginDays > this.maxConsecutiveLoginDays) {
                this.maxConsecutiveLoginDays = this.consecutiveLoginDays;
            }
        } else {
            // 非连续登录
            this.totalLoginDays++;
            this.consecutiveLoginDays = 1;
        }
        this.lastLoginDate = loginDate;
    }

    /**
     * 更新活跃天数统计
     */
    public void updateActiveDays() {
        this.totalActiveDays = (this.totalActiveDays == null ? 0 : this.totalActiveDays) + 1;
    }

    /**
     * 更新平均会话时长
     */
    public void updateAvgSessionDuration(int sessionDurationMinutes) {
        if (this.avgSessionDurationMinutes == null || this.avgSessionDurationMinutes == 0) {
            this.avgSessionDurationMinutes = sessionDurationMinutes;
        } else {
            // 简单的移动平均
            this.avgSessionDurationMinutes = (this.avgSessionDurationMinutes + sessionDurationMinutes) / 2;
        }
    }

    /**
     * 计算用户活跃度评分（0-100）
     */
    public int calculateActivityScore() {
        int score = 0;
        
        // 登录频率 (30分)
        if (consecutiveLoginDays >= 30) score += 30;
        else if (consecutiveLoginDays >= 14) score += 25;
        else if (consecutiveLoginDays >= 7) score += 20;
        else if (consecutiveLoginDays >= 3) score += 15;
        else if (consecutiveLoginDays >= 1) score += 10;
        
        // 功能使用度 (40分)
        int totalActions = totalScriptsGenerated + totalTemplatesCreated + totalTemplatesUsed;
        if (totalActions >= 100) score += 40;
        else if (totalActions >= 50) score += 35;
        else if (totalActions >= 20) score += 30;
        else if (totalActions >= 10) score += 25;
        else if (totalActions >= 5) score += 20;
        else if (totalActions >= 1) score += 15;
        
        // 使用时长 (30分)
        if (avgSessionDurationMinutes >= 60) score += 30;
        else if (avgSessionDurationMinutes >= 30) score += 25;
        else if (avgSessionDurationMinutes >= 15) score += 20;
        else if (avgSessionDurationMinutes >= 5) score += 15;
        else if (avgSessionDurationMinutes >= 1) score += 10;
        
        return Math.min(score, 100);
    }

    /**
     * 获取用户等级
     */
    public String getUserLevel() {
        int score = calculateActivityScore();
        if (score >= 90) return "专家";
        else if (score >= 75) return "高级";
        else if (score >= 60) return "中级";
        else if (score >= 40) return "初级";
        else return "新手";
    }

    /**
     * 检查是否为活跃用户
     */
    public boolean isActiveUser() {
        return consecutiveLoginDays >= 7 || 
               (totalScriptsGenerated + totalTemplatesCreated + totalTemplatesUsed) >= 10;
    }
}
